﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Experimentor
{
    public class Sequence : IComparable, ICloneable
    {
        private int _seqOrder;
        private string _seqName;
        private string _sheetName;
        private int _seqFromset;
        private int _seqToset;
        private bool _seqRandomize;
        private SlideLayout _seqLayout;
        private string _seqLayoutArgs;
        private string _seqEvents;
        private SortableBindingList<SequencePart> _seqParts;

        public Sequence()
        {
            this._seqOrder = 0;
            this._seqName = "<enter name>";
            this._sheetName = "<enter Excel sheet name; max. 30 chars>";
            this._seqRandomize = false;
            this._seqLayout = new SlideLayout_Single();
            this._seqLayoutArgs = "";
            this._seqEvents = "";
            this._seqParts = new SortableBindingList<SequencePart>();
        }

        public int Order
        {
            get { return this._seqOrder; }
            set { this._seqOrder = value; }
        }

        public string Name
        {
            get { return this._seqName; }
            set { this._seqName = value; }
        }

        public string SheetName
        {
            get { return this._sheetName; }
            set { this._sheetName = value; }
        }

        public int Fromset
        {
            get { return this._seqFromset; }
            set { this._seqFromset = value; }
        }

        public int Toset
        {
            get { return this._seqToset; }
            set { this._seqToset = value; }
        }

        public bool Randomize
        {
            get { return this._seqRandomize; }
            set { this._seqRandomize = value; }
        }

        public string SlideLayout
        {
            get { return this._seqLayout.GetType().Name; }
            set
            {
                try
                {
                    Type sltype = Type.GetType("Experimentor." + value);
                    this._seqLayout = Activator.CreateInstance(sltype) as SlideLayout;
                } catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show("FATAL: " + ex.Message, "Fatal Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    this._seqLayout = new SlideLayout_Single();
                }
            }
        }

        public SlideLayout getLayout()
        {
            return this._seqLayout;
        }

        public string LayoutArgs
        {
            get { return this._seqLayoutArgs; }
            set { this._seqLayoutArgs = value; }
        }

        public string Events
        {
            get { return this._seqEvents; }
            set { this._seqEvents = value; }
        }
        
        public BindingList<SequencePart> Parts
        {
            get { return this._seqParts; }
            private set { }
        }

        public bool hasSaveParts()
        {
            bool save = false;
            foreach (SequencePart part in this._seqParts) if (part.Save)
            {
                save = true;
                break;
            }
            return save;
        }

        int IComparable.CompareTo(object obj)
        {
            if (obj.GetType().Equals(this.GetType()))
            {
                return this.Order - (obj as Sequence).Order;
            }
            else return 0;
        }

        public object Clone()
        {
            Sequence newSequence = (Sequence)this.MemberwiseClone();
            newSequence._seqLayout = this._seqLayout;
            newSequence._seqParts = new SortableBindingList<SequencePart>();
            foreach (SequencePart part in this._seqParts) newSequence._seqParts.Add((SequencePart)part.Clone());
            return newSequence;
        }
    }

    public class SequencePart : IComparable, ICloneable
    {
        private int _spOrder;
        private int _spSlide;
        private int _spPosition;
        private double _spProbability;
        private int _spShowMin;
        private int _spShowMax;
        private int _spShowStep;
        private bool _spShowBalanced;
        private UserAction _spUserAction;
        private string _spUserActionArgs;
        private bool _spSave;
        private string _spEvents;

        public SequencePart()
        {
            this._spOrder = 0;
            this._spSlide = 0;
            this._spPosition = 0;
            this._spProbability = 1;
            this._spUserAction = new UserAction_None();
        }

        public int Order
        {
            get { return this._spOrder; }
            set { this._spOrder = value; }
        }
        
        public int Slide
        {
            get { return this._spSlide; }
            set { this._spSlide = value; }
        }

        public int Position
        {
            get { return this._spPosition; }
            set { this._spPosition = value; }
        }

        public double Probability
        {
            get { return this._spProbability; }
            set { this._spProbability = value; }
        }

        public int ShowMin
        {
            get { return this._spShowMin; }
            set { this._spShowMin = value; }
        }

        public int ShowMax
        {
            get { return this._spShowMax; }
            set { this._spShowMax = value; }
        }

        public int ShowStep
        {
            get { return this._spShowStep; }
            set { this._spShowStep = value; }
        }

        public bool ShowBalanced
        {
            get { return this._spShowBalanced; }
            set { this._spShowBalanced = value; }
        }

        public string UserAction
        {
            get { return this._spUserAction.GetType().Name; }
            set
            {
                try
                {
                    Type sltype = Type.GetType("Experimentor." + value);
                    this._spUserAction = Activator.CreateInstance(sltype) as UserAction;
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show("FATAL: " + ex.Message, "Fatal Error", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
                    this._spUserAction = new UserAction_None();
                }
            }
        }

        public string UserActionArgs
        {
            get { return this._spUserActionArgs; }
            set { this._spUserActionArgs = value; }
        }

        public UserAction getUserAction()
        {
            return this._spUserAction;
        }

        public bool Save
        {
            get { return this._spSave; }
            set { this._spSave = value; }
        }
        
        public string Events
        {
            get { return this._spEvents; }
            set { this._spEvents = value; }
        }

        int IComparable.CompareTo(object obj)
        {
            if (obj.GetType().Equals(this.GetType()))
            {
                return this.Order - (obj as SequencePart).Order;
            }
            else return 0;
        }

        public object Clone()
        {
            SequencePart newpart = (SequencePart)this.MemberwiseClone();
            newpart._spUserAction = this._spUserAction;
            return newpart;
        }
    }
}
